# 映射类定义与添加记录
from sqlalchemy import create_engine, Column, Integer, String, Date
from sqlalchemy.orm import declarative_base, sessionmaker, Mapped, mapped_column
import datetime

engine = create_engine('mysql://root:ZHabc123.@shc.chenzao.fun:13306/testdb', echo=True)

# 定义映射关系类
Base = declarative_base()

class Person(Base):
    __tablename__ = 'person'
    
    id = Column(Integer, primary_key=True)
    name = Column(String(128), nullable=False, unique=True)
    birthday = Column(Date, nullable=False)
    address = Column(String(255), nullable=True)
  
# 2.0新映射方式
class Customer(Base):
    __tablename__ = 'customer'
    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column(String(128), nullable=False, unique=True)
    birthday: Mapped[datetime.datetime] = mapped_column(nullable=False)
    address: Mapped[str] = mapped_column(String(255), nullable=True)

# 使用 Annotated 映射方式，需要使用 Annotated 装饰器，类型注解
from typing_extensions import Annotated
from sqlalchemy.sql import func
int_pk = Annotated[int, mapped_column(primary_key=True)]
timestamp_default_now = Annotated[datetime.datetime, mapped_column(nullable=False, server_default=func.now())]

class CustomerTwo(Base):
    __tablename__ = 'customer_two'
    id: Mapped[int_pk]
    name: Mapped[str] = mapped_column(String(128), nullable=False, unique=True)
    birthday: Mapped[datetime.datetime] = mapped_column(nullable=False)
    address: Mapped[str] = mapped_column(String(255), nullable=True)
    create_time: Mapped[timestamp_default_now]





Base.metadata.create_all(engine)

# 创建 Session 对象，连接数据库
Session = sessionmaker(bind=engine)
session = Session()
# 开始操作数据库，添加记录
# p = Person(name='zhangsan', birthday='2024-05-23', address='北京')
# session.add(p)

# 添加多个对象
# person_list = [
#   Person(name='ECHO', birthday='2024-04-23', address='北京'),
#   Person(name='TUNNY', birthday='2024-03-23', address='西安'),
# ]
# session.add_all(person_list)

# session.commit()


# 查询
# .all() 查询所有的数据
# .filter() 条件查询
# .first() 拿出结果集里的第一条记录, 如果结果集是空的, 返回 None
# .one() 结果集里只有一条数据的时候，可以使用 one，否则会报错。条件很苛刻，一般用不到。
# .scalar() 如果只有一条记录，或者没有记录，可以使用 scale， 如果结果集有多个，那么会报错，如果结果集为空，那么返回 None
# result = session.query(Person).all()
result = session.query(Person).filter(Person.address == '北京2').first()
print(result)
# for person in result:
#     print(person.name, person.birthday)


# 修改 
# 1. 拿到对象，直接进行修改
# 2. 直接进行 update 修改
# person = session.query(Person).filter(Person.id == '1').scalar()
# if person:
#     person.name = '测试修改'
# session.commit()

# session.query(Person).filter(Person.id == '1').update({'name': '测试修改2'})
session.query(Person).filter(Person.id == '1').update({
  Person.address: '北京222'
})
session.commit()


